home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / dev / misc / libx11.lha / libX11 / clipping.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-22  |  8.6 KB  |  334 lines

  1. /* Copyright (c) 1996 by Terje Pedersen.  All Rights Reserved   */
  2. /*                                                              */
  3. /* By using this code you will agree to these terms:            */
  4. /*                                                              */
  5. /* 1. You may not use this code for profit in any way or form   */
  6. /*    unless an agreement with the author has been reached.     */
  7. /*                                                              */
  8. /* 2. The author is not responsible for any damages caused by   */
  9. /*    the use of this code.                                     */
  10. /*                                                              */
  11. /* 3. All modifications are to be released to the public.       */
  12. /*                                                              */
  13. /* Thats it! Have fun!                                          */
  14. /* TP                                                           */
  15. /*                                                              */
  16.  
  17. /***
  18.    NAME
  19.      clipping
  20.    PURPOSE
  21.      add clipping support in libX11
  22.    NOTES
  23.      
  24.    HISTORY
  25.      Terje Pedersen - Oct 22, 1994: Created.
  26. ***/
  27.  
  28. #include <intuition/intuition.h>
  29. #include <intuition/intuitionbase.h>
  30.  
  31. #include <graphics/gfx.h>
  32. #include <graphics/gfxbase.h>
  33. #include <graphics/gfxmacros.h>
  34. #include <graphics/displayinfo.h>
  35. #include <devices/timer.h>
  36.  
  37. #include <proto/intuition.h>
  38. #include <proto/graphics.h>
  39. #include <proto/gadtools.h>
  40. #include <proto/layers.h>
  41.  
  42. #include <dos.h>
  43. #include <signal.h>
  44. #include <stdlib.h>
  45. #include <time.h>
  46. #include <stdio.h>
  47.  
  48. #include "libX11.h"
  49.  
  50. #define XLIB_ILLEGAL_ACCESS 1
  51.  
  52. #include <X11/X.h>
  53. #include <X11/Xlib.h>
  54. #include <X11/Xutil.h>
  55. #include <X11/Intrinsic.h>
  56. #include <X11/IntrinsicP.h>
  57. #include <X11/CoreP.h>
  58.  
  59. /*
  60. #include <libraries/mui.h>
  61. #include <proto/muimaster.h>
  62. */
  63. #include "amigax_proto.h"
  64. #include "amiga_x.h"
  65.  
  66. ClippingGlobals_s CG;
  67.  
  68. int XSetClipMask(Display *,GC,Pixmap);
  69.  
  70. extern int X_relx,X_rely;
  71. extern struct Screen *Scr,*wb;
  72. extern struct BitMap *alloc_bitmap(int,int,int,int);
  73. extern int free_bitmap(struct BitMap *),wbapp;
  74.  
  75. void unclipWindow(struct Layer *l);
  76. struct Region *clipWindow(struct Layer *l,
  77.                  LONG minX, LONG minY, LONG maxX, LONG maxY);
  78. void clip_begin(int,int,int,int);
  79. void clip_exclude(int,int,int,int);
  80. void clip_end(struct Window *);
  81.  
  82. /*clipping from rkm */
  83.  
  84. #define DOCLIPPING
  85. /*
  86. #define DEBUGCLIPPING
  87. */
  88. /*
  89. ** clipWindow()
  90. ** Clip a window to a specified rectangle (given by upper left and
  91. ** lower right corner.)  the removed region is returned so that it
  92. ** may be re-installed later.
  93. */
  94. struct Region *clipWindow(struct Layer *l,
  95.     LONG minX, LONG minY, LONG maxX, LONG maxY)
  96. {
  97. #ifdef DOCLIPPING
  98.   struct Region    *new_region,*retregion;
  99.   struct Rectangle  my_rectangle;
  100.  
  101. #ifdef DEBUGCLIPPING
  102.   printf("clipWindow %d\n",l);
  103. #endif /* DEBUGCLIPPING */
  104.  
  105. /* set up the limits for the clip */
  106.   my_rectangle.MinX = minX;
  107.   my_rectangle.MinY = minY;
  108.   my_rectangle.MaxX = maxX;
  109.   my_rectangle.MaxY = maxY;
  110.  
  111. /* get a new region and OR in the limits. */
  112.   if (NULL != (new_region = NewRegion())){
  113.     if (FALSE == OrRectRegion(new_region, &my_rectangle)){
  114.       DisposeRegion(new_region);
  115.       new_region = NULL;
  116.     }
  117.   }
  118.  
  119. /* Install the new region, and return any existing region.
  120. ** If the above allocation and region processing failed, then
  121. ** new_region will be NULL and no clip region will be installed.
  122. */
  123.   retregion=InstallClipRegion(l, new_region);
  124.   return(retregion);
  125. #endif
  126. }
  127.  
  128. /*
  129. ** unclipWindow()
  130. **
  131. ** Used to remove a clipping region installed by clipWindow() or
  132. ** clipWindowToBorders(), disposing of the installed region and
  133. ** reinstalling the region removed.
  134. */
  135. void unclipWindow(struct Layer *l)
  136. {
  137. #ifdef DOCLIPPING
  138.   struct Region     *old_region;
  139. #ifdef DEBUGCLIPPING
  140.   printf("unclipWindow %d\n",l);
  141. #endif /* DEBUGCLIPPING */
  142.   /* Remove any old region by installing a NULL region,
  143.    ** then dispose of the old region if one was installed.
  144.    */
  145.   if (NULL != (old_region = InstallClipRegion(l, NULL)))
  146.     DisposeRegion(old_region);
  147. #endif
  148. }
  149.  
  150. XSetClipRectangles(d,gc, clip_x_origin,
  151.            clip_y_origin, rectangles, n, ordering)
  152.      Display *d;
  153. /*     Drawable win;*/
  154.      GC gc;
  155.      int clip_x_origin, clip_y_origin;
  156.      XRectangle *rectangles;
  157.      int n;
  158.      int ordering;
  159. {
  160.   struct Region *old_region;
  161.   struct Window *win;
  162. #ifdef DOCLIPPING
  163.   Window w=RootWindowOfScreen(DefaultScreenOfDisplay(d));
  164. #ifdef DEBUGXEMUL_ENTRY
  165.   printf("(clipping)XsetClipRectangles [%d]\n",w);
  166. #endif
  167. /*
  168.   printf("rect [%d %d] [%d %d]\n",rectangles[0].x,rectangles[0].y,rectangles[0].x+rectangles[0].width-1,rectangles[0].y+rectangles[0].height-1);
  169. */
  170.   if( w==ROOTID ){
  171.     return;
  172.   }
  173.   win=X11DrawablesWindows[X11DrawablesMap[w]];
  174.   if(!win) return 0;
  175.   if(!win->WLayer){
  176.     return;
  177.   }
  178.   if(win && X11ActualWindows[X11DrawablesMap[w]].mapped){
  179.     if(CG.pPreviousLayer){
  180.       unclipWindow(CG.pPreviousLayer);
  181.       CG.pPreviousLayer=NULL;
  182.     }
  183.     if(old_region=clipWindow(win->WLayer,X_relx+rectangles[0].x,X_rely+rectangles[0].y,X_relx+rectangles[0].x+rectangles[0].width-1,X_rely+rectangles[0].y+rectangles[0].height-1)){
  184.       DisposeRegion(old_region);
  185.       CG.pPreviousLayer=win->WLayer;
  186.     } else CG.pPreviousLayer=NULL;
  187.   }
  188.   prevwin=-1;
  189. #endif
  190. }
  191.  
  192. /*
  193. _SetBmClip(struct BitMap *bm,struct RastPort *rp){
  194.   if(old_region=clipWindow(rp->Layer,0,0,bm->BytesPerRow*8-1,bm->Rows-1))
  195.     DisposeRegion(old_region);
  196. }
  197. */
  198.  
  199. XSetClipMask(d,gc,pixmap)
  200.      Display *d;
  201. /*     Object *win;*/
  202.      GC gc;
  203.      Pixmap pixmap;
  204. {
  205. #ifdef DOCLIPPING
  206.   struct BitMap *bm=X11DrawablesBitmaps[X11DrawablesMap[pixmap]].pBitMap;
  207. /*
  208.   Window w=RootWindowOfScreen(DefaultScreenOfDisplay(d));
  209. */
  210. #ifdef DEBUGXEMUL
  211.   if(bm)
  212.     printf("(clipping)XSetClipMask [%d,%d]\n",bm->BytesPerRow*8,bm->Rows);
  213.   else
  214.     printf("(clipping)XSetClipMask\n");
  215. #endif
  216.  
  217.  
  218.   if(pixmap==None&&wbapp){
  219. /*
  220.     struct Window *win=X11DrawablesWindows[X11DrawablesMap[w]];
  221.     if(win) unclipWindow(win->WLayer);*/
  222.   }
  223.   if(pixmap){
  224.     int BmWidth=GetBitMapAttr(bm,BMA_WIDTH);
  225.     int BmHeight=GetBitMapAttr(bm,BMA_HEIGHT);
  226. /*
  227.     int BmDepth=GetBitMapAttr(bm,BMA_DEPTH);
  228.     if(BmDepth!=1) {printf("wrong depth!\n");getchar();}*/
  229.     CG.bNeedClip=1;
  230. /*    if(CG.pClipBM) {printf("already got one!\n");getchar();}*/
  231.     CG.pClipBM=alloc_bitmap(BmWidth,BmHeight,1,BMF_CLEAR);
  232.     BltBitMap(bm,0,0,CG.pClipBM,0,0,BmWidth,BmHeight,0xC0,0xff,NULL);
  233. /*    memcpy(&CG.pClipBM->Planes[0],&bm->Planes[0],bm->BytesPerRow*bm->Rows);*/
  234.   }else{
  235.     CG.bNeedClip=0;
  236.     if(CG.pClipBM) free_bitmap(CG.pClipBM);
  237.     CG.pClipBM=NULL;
  238.   }
  239. #endif
  240. }
  241.  
  242. void clip_begin(minX,minY,maxX,maxY){
  243. #ifdef DOCLIPPING
  244.   struct Rectangle my_rectangle;
  245. #ifdef DEBUGXEMUL
  246.   printf("clip_begin %d %d %d %d\n",minX,minY,maxX,maxY);
  247. #endif
  248.   my_rectangle.MinX = minX;
  249.   my_rectangle.MinY = minY;
  250.   my_rectangle.MaxX = maxX;
  251.   my_rectangle.MaxY = maxY;
  252.   if (CG.pClipRegion = NewRegion()){
  253.     OrRectRegion(CG.pClipRegion, &my_rectangle);
  254.   }
  255. #endif
  256. }
  257.  
  258. void clip_exclude(X,Y,width,height){
  259. #ifdef DOCLIPPING
  260.   int minX=X,minY=Y,maxX=X+width,maxY=Y+height;
  261.   struct Rectangle my_rectangle;
  262.  
  263. #ifdef DEBUGXEMUL
  264.   printf("clip_exclude %d %d %d %d\n",minX,minY,maxX,maxY);
  265. #endif
  266.  
  267.   my_rectangle.MinX = minX;
  268.   my_rectangle.MinY = minY;
  269.   my_rectangle.MaxX = maxX;
  270.   my_rectangle.MaxY = maxY;
  271.   if(!XorRectRegion(CG.pClipRegion, &my_rectangle))
  272.     printf("clip_exclude failed!\n");
  273. #endif
  274. }
  275.  
  276. void clip_end(struct Window *win){
  277. #ifdef DOCLIPPING
  278.   struct Region *old_region;
  279. #ifdef DEBUGXEMUL
  280.   printf("win %d\n",win);
  281. #endif
  282.   old_region=InstallClipRegion(win->WLayer, CG.pClipRegion);
  283.   if(old_region!=NULL) DisposeRegion(old_region);
  284. #endif
  285. }
  286.  
  287. XSetPlaneMask(display, gc, plane_mask)
  288.      Display *display;
  289.      GC gc;
  290.      unsigned long plane_mask;
  291. {
  292. #ifdef DEBUGXEMUL
  293.   printf("(clipping)XSetPlaneMask [%d]\n",plane_mask);
  294. #endif
  295.   if(Scr&&Scr!=wb)
  296.     SetWriteMask(&Scr->RastPort,plane_mask);
  297.   return(0);
  298. }
  299.  
  300. XSetClipOrigin(display, gc, clip_x_origin, clip_y_origin)
  301.      Display *display;
  302.      GC gc;
  303.      int clip_x_origin, clip_y_origin;
  304. {
  305. #ifdef DEBUGXEMUL
  306.   printf("XSetClipOrigin [%d,%d]\n",clip_x_origin,clip_y_origin);
  307. #endif
  308.   CG.nXClipOrigin=clip_x_origin;
  309.   CG.nYClipOrigin=clip_y_origin;
  310.   return(0);
  311. }
  312.  
  313. struct Region *clipWindowToBorders(struct Window *win)
  314. {
  315.   return(clipWindow(win->WLayer, win->BorderLeft, win->BorderTop,
  316.             win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1));
  317. }
  318.  
  319. VOID clip_test(struct Window *win){
  320. #ifdef DOCLIPPING
  321.   struct Region    *old_region;
  322.   
  323.   if (NULL != (old_region = clipWindowToBorders(win)))
  324.     DisposeRegion(old_region);
  325. #endif
  326. }
  327.  
  328. void X11init_clipping(void){
  329.   memset(&CG,0,sizeof(ClippingGlobals_s));
  330. }
  331.  
  332. void X11exit_clipping(void){
  333. }
  334.